import java.util.ArrayList;
import java.util.HashMap;


public class NetworkGraph {

	int nodeCount;
	Node[] nodes = new Node[100];
	HashMap nodeTable = new HashMap();

	int edgeCount;
	Edge[] edges = new Edge[100];

	final int nodeColor   = 220; //220
	final int selectColor = 180;
	final int fixedColor  = 120;
	final int edgeColor   = 180;
	final int nodeBackColor = GLOBAL.processing.color(50,50,50);

	final int xOffset = 15;
	final int yOffset = 15;

	int relaxCount;
	int numberOfCenters;
	int numberOfCentersCreated;

	public NetworkGraph(){
		//add edges
		loadData();
	}


	public void loadData(){
		edges = new Edge[100];
		nodes = new Node[100];
		edgeCount=0;
		nodeCount=0;
		relaxCount=0;
		numberOfCentersCreated=0;
		nodeTable = new HashMap();
		numberOfCenters = GLOBAL.affineArtistsToShow.size();
		numberOfCentersCreated = 0;

		for(int i=0;i<GLOBAL.affineArtistsToShow.size();i++){
			ArrayList<Artist> affineArtists = GLOBAL.affineArtists.get(GLOBAL.affineArtistsToShow.get(i));
			if(affineArtists != null)
				for(int j=0; j< 6 && j<affineArtists.size(); j++){
					//System.out.println("add edge "+j+" "+GLOBAL.affineArtistsToShow.get(i).arName);
					boolean center=false;
					for(int k=0;k<GLOBAL.affineArtistsToShow.size();k++){
						center = affineArtists.get(j).arid.equalsIgnoreCase(GLOBAL.affineArtistsToShow.get(k).arid);
						if (center) break;
					}
					addEdge(GLOBAL.affineArtistsToShow.get(i),affineArtists.get(j),center);
				}	
		}
	}


	void addEdge(Artist fromLabel, Artist toLabel,boolean center) {
		Node from = findNode(fromLabel,true);
		Node to = findNode(toLabel,center);
		from.increment();
		from.fixed = true;
		to.increment();
		if(center)
			to.fixed = true;

		for (int i = 0; i < edgeCount; i++) {
			if (edges[i].from == from && edges[i].to == to) {
				edges[i].increment();
				return;
			}
		} 
		float len = 150*(1+GLOBAL.processing.random(2));
		if(len >250)len = 250;
		Edge e = new Edge(from, to,len);
		e.increment();
		if (edgeCount == edges.length) {
			edges = (Edge[]) GLOBAL.processing.expand(edges);
		}
		edges[edgeCount++] = e;
	}


	Node findNode(Artist artist, boolean central) {
		Node n = (Node) nodeTable.get(artist);
		if (n == null) {
			return addNode(artist,central);
		}
		return n;
	}


	Node addNode(Artist artist, boolean central) {
		Node n = new Node(artist,central);  
		if (nodeCount == nodes.length) {
			nodes = (Node[]) GLOBAL.processing.expand(nodes);
		}
		nodeTable.put(artist, n);
		nodes[nodeCount++] = n;  
		return n;
	}

	Node selection; 


	void mousePressed() {
		// Ignore anything greater than this distance
		float closest = 30;
		for (int i = 0; i < nodeCount; i++) {
			Node n = nodes[i];
			float d = GLOBAL.processing.dist(GLOBAL.processing.mouseX, GLOBAL.processing.mouseY, n.x, n.y);
			if (d < closest) {
				selection = n;
				closest = d;
			}
		}
		if (selection != null) {
			if (GLOBAL.processing.mouseButton == GLOBAL.processing.LEFT) {
				selection.fixed = true;
			} else if (GLOBAL.processing.mouseButton == GLOBAL.processing.RIGHT) {
				selection.fixed = false;
			}
			if (GLOBAL.processing.mouseEvent.getClickCount()==2){
				Artist a = selection.artist;
				for(Artist ar: GLOBAL.artistsSelected){
					if(ar.arid.equalsIgnoreCase(a.arid))
						return;
				}
				for(Artist ar: GLOBAL.groupsSelected){
					if(ar.arid.equalsIgnoreCase(a.arid))
						return;
				}
				for(Artist ar: GLOBAL.personsSelected){
					if(ar.arid.equalsIgnoreCase(a.arid))
						return;
				}
				Artist.addArtist(a.arid, a.arName);
			}
		}
	}


	void mouseDragged() {
		if (selection != null) {
			//			selection.x = GLOBAL.processing.mouseX;
			//			selection.y = GLOBAL.processing.mouseY;

			selection.x = GLOBAL.processing.constrain(GLOBAL.processing.mouseX, 0+xOffset, GLOBAL.width-250-xOffset);
			selection.y = GLOBAL.processing.constrain(GLOBAL.processing.mouseY, GLOBAL.infoPanel.y+yOffset, GLOBAL.height-yOffset);
		}
	}


	void mouseReleased() {
		selection = null;
	}


	void draw() {
		
		
		
		if(edgeCount==0){
		GLOBAL.processing.textFont(GLOBAL.plotFont,16);  
		GLOBAL.processing.fill(GLOBAL.textBoldColor);
		GLOBAL.processing.textAlign(GLOBAL.processing.CENTER);  
		GLOBAL.processing.text("Click on the name of an artist/group/person on the right to add it to the graph",
				(GLOBAL.width-GLOBAL.infoPanel.width)/2,(GLOBAL.height-20-GLOBAL.graphsArea.y)/2+GLOBAL.graphsArea.y);
		}
		if(relaxCount<200){
			for (int i = 0 ; i < GLOBAL.graphsArea.networkGraph.edgeCount ; i++) {
				edges[i].relax();
			}
			for (int i = 0; i < GLOBAL.graphsArea.networkGraph.nodeCount; i++) {
				nodes[i].relax();
			}
			for (int i = 0; i < GLOBAL.graphsArea.networkGraph.nodeCount; i++) {
				nodes[i].update();
			}
		}
		for (int i = 0 ; i < GLOBAL.graphsArea.networkGraph.edgeCount ; i++) {
			edges[i].draw();
		}
		for (int i = 0 ; i < GLOBAL.graphsArea.networkGraph.nodeCount ; i++) {
			nodes[i].draw();
		}

	}





}
